<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>学生座位表调整工具（讲台两侧+自定义布局）</title>
    <script src="https://unpkg.com/xlsx/dist/xlsx.full.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Segoe UI', 'Microsoft YaHei', sans-serif;
        }
        
        body {
            background: linear-gradient(135deg, #f5f7fa 0%, #e4edf5 100%);
            min-height: 100vh;
            padding: 20px;
            color: #333;
        }
        
        .container {
            max-width: 1200px;
            margin: 0 auto;
        }
        
        header {
            text-align: center;
            padding: 25px 0;
            margin-bottom: 30px;
            background: linear-gradient(90deg, #1a73e8, #0d47a1);
            color: white;
            border-radius: 12px;
            box-shadow: 0 6px 18px rgba(0, 0, 0, 0.18);
        }
        
        h1 {
            font-size: 2.6rem;
            margin-bottom: 10px;
            text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25);
        }
        
        .subtitle {
            font-size: 1.15rem;
            opacity: 0.92;
            letter-spacing: 0.5px;
        }
        
        .toolbar {
            display: flex;
            justify-content: space-between;
            flex-wrap: wrap;
            gap: 18px;
            padding: 22px;
            background: linear-gradient(135deg, #ffffff, #f8f9fa);
            border-radius: 12px;
            box-shadow: 0 6px 15px rgba(0, 0, 0, 0.1);
            margin-bottom: 30px;
            border: 1px solid #e1e5eb;
        }
        
        .btn-group {
            display: flex;
            gap: 14px;
            flex-wrap: wrap;
        }
        
        .btn {
            padding: 14px 28px;
            background: linear-gradient(135deg, #4285f4, #1a73e8);
            color: white;
            border: none;
            border-radius: 50px;
            cursor: pointer;
            font-weight: 600;
            font-size: 1.05rem;
            transition: all 0.3s ease;
            box-shadow: 0 5px 12px rgba(66, 133, 244, 0.35);
            display: flex;
            align-items: center;
            gap: 10px;
        }
        
        .btn:hover {
            transform: translateY(-4px);
            box-shadow: 0 8px 15px rgba(66, 133, 244, 0.45);
        }
        
        .btn:active {
            transform: translateY(1px);
            box-shadow: 0 3px 8px rgba(66, 133, 244, 0.35);
        }
        
        .btn-random {
            background: linear-gradient(135deg, #fbbc05, #e6a000);
            box-shadow: 0 5px 12px rgba(251, 188, 5, 0.35);
        }
        
        .btn-reset {
            background: linear-gradient(135deg, #ea4335, #d32d20);
            box-shadow: 0 5px 12px rgba(234, 67, 53, 0.35);
        }
        
        .btn-pdf {
            background: linear-gradient(135deg, #e53935, #b71c1c);
            box-shadow: 0 5px 12px rgba(229, 57, 53, 0.35);
        }
        
        .btn-height {
            background: linear-gradient(135deg, #34a853, #0f9d58);
            box-shadow: 0 5px 12px rgba(52, 168, 83, 0.35);
        }
        
        .file-upload {
            position: relative;
            display: inline-block;
            overflow: hidden;
            border-radius: 50px;
            box-shadow: 0 4px 10px rgba(66, 133, 244, 0.3);
        }
        
        .file-upload input {
            position: absolute;
            left: 0;
            top: 0;
            opacity: 0;
            width: 100%;
            height: 100%;
            cursor: pointer;
        }
        
        /* 教室布局 */
        .classroom-container {
            background: white;
            border-radius: 14px;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.12);
            overflow: hidden;
            margin-bottom: 30px;
            border: 1px solid #e9ecef;
        }
        
        .classroom-header {
            background: linear-gradient(135deg, #6a11cb, #2575fc);
            color: white;
            text-align: center;
            padding: 15px;
            font-weight: bold;
            font-size: 1.2rem;
        }
        
        .classroom {
            display: grid;
            grid-template-columns: repeat(8, 1fr);
            gap: 14px;
            padding: 25px;
        }
        
        /* 讲台行布局 */
        .teacher-row {
            grid-column: 1 / -1;
            display: grid;
            grid-template-columns: 1fr 1fr 2fr 2fr 1fr 1fr;
            gap: 14px;
            height: 110px; /* 增加讲台两侧座位高度 */
            margin-bottom: 25px;
        }
        
        /* 讲台两侧座位 */
        .side-seat {
            height: 100%;
            border-radius: 10px;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            padding: 10px;
            cursor: move;
            transition: all 0.3s ease;
            box-shadow: 0 4px 10px rgba(0, 0, 0, 0.12);
            position: relative;
            overflow: hidden;
            border: 2px solid transparent;
        }
        
        /* 讲台 */
        .teacher-desk {
            grid-column: 3 / span 2;
            background: linear-gradient(135deg, #8e2de2, #4a00e0);
            border-radius: 10px;
            display: flex;
            justify-content: center;
            align-items: center;
            color: white;
            font-weight: bold;
            font-size: 1.3rem;
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.15);
            text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.3);
        }
        
        /* 普通座位样式 - 增加高度以容纳更多内容 */
        .seat {
            height: 120px; /* 增加座位高度 */
            border-radius: 10px;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            padding: 12px;
            cursor: move;
            transition: all 0.3s ease;
            box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
            position: relative;
            overflow: hidden;
            border: 2px solid transparent;
        }
        
        .seat.empty {
            background: linear-gradient(135deg, #f0f0f0, #e0e0e0);
            color: #999;
        }
        
        .seat.male {
            background: linear-gradient(135deg, #64b5f6, #42a5f5);
            border-color: #bbdefb;
        }
        
        .seat.female {
            background: linear-gradient(135deg, #f48fb1, #f06292);
            border-color: #f8bbd0;
        }
        
        .side-seat.empty {
            background: linear-gradient(135deg, #f0f0f0, #e0e0e0);
            color: #999;
        }
        
        .side-seat.male {
            background: linear-gradient(135deg, #64b5f6, #42a5f5);
            border-color: #bbdefb;
        }
        
        .side-seat.female {
            background: linear-gradient(135deg, #f48fb1, #f06292);
            border-color: #f8bbd0;
        }
        
        .dragging {
            opacity: 0.7;
            transform: scale(0.95);
            box-shadow: 0 0 20px rgba(66, 133, 244, 0.7);
            z-index: 10;
        }
        
        .drag-over {
            background-color: rgba(255, 235, 59, 0.4) !important;
            transform: scale(1.06);
            border-color: #ffc107 !important;
        }
        
        /* 位置信息样式 */
        .seat-position {
            position: absolute;
            top: 8px;
            left: 8px;
            font-size: 0.85rem;
            font-weight: 700;
            color: #555;
            background: rgba(255, 255, 255, 0.7);
            border-radius: 20px;
            width: 24px;
            height: 24px;
            display: flex;
            align-items: center;
            justify-content: center;
        }
        
        /* 姓名样式 - 增大字号和宽度确保显示完整 */
        .student-name {
            font-size: 1.25rem;
            font-weight: 700;
            margin-bottom: 8px;
            text-align: center;
            width: 100%;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
            padding: 0 5px;
        }
        
        /* 性别和身高容器 - 并排显示 */
        .student-details {
            display: flex;
            justify-content: center;
            gap: 8px;
            width: 100%;
            padding: 0 5px;
        }
        
        /* 性别和身高样式 */
        .student-gender, .student-height {
            font-size: 0.9rem;
            padding: 3px 10px;
            border-radius: 20px;
            background: rgba(255, 255, 255, 0.4);
            font-weight: 600;
            white-space: nowrap;
        }
        
        .instructions {
            background: linear-gradient(135deg, #ffffff, #f8f9fa);
            padding: 28px;
            border-radius: 14px;
            box-shadow: 0 6px 15px rgba(0, 0, 0, 0.08);
            margin-top: 25px;
            border: 1px solid #e9ecef;
        }
        
        .instructions h2 {
            color: #1a73e8;
            margin-bottom: 20px;
            font-size: 1.6rem;
            text-align: center;
            padding-bottom: 12px;
            border-bottom: 2px solid #e0e7ff;
        }
        
        .instructions ul {
            padding-left: 30px;
            line-height: 1.85;
        }
        
        .instructions li {
            margin-bottom: 14px;
            font-size: 1.05rem;
            position: relative;
        }
        
        .instructions li:before {
            content: "•";
            color: #1a73e8;
            font-weight: bold;
            display: inline-block;
            width: 1em;
            margin-left: -1em;
            font-size: 1.3rem;
        }
        
        .status-bar {
            display: flex;
            justify-content: space-between;
            padding: 18px 25px;
            background: linear-gradient(135deg, #ffffff, #f8f9fa);
            border-radius: 14px;
            box-shadow: 0 6px 15px rgba(0, 0, 0, 0.08);
            margin-top: 25px;
            font-size: 1rem;
            border: 1px solid #e9ecef;
            flex-wrap: wrap;
            gap: 12px;
        }
        
        .stats-container {
            display: flex;
            flex-wrap: wrap;
            gap: 12px;
            width: 100%;
            justify-content: center;
        }
        
        .stats-box {
            background: rgba(255, 255, 255, 0.7);
            border-radius: 10px;
            padding: 12px 20px;
            min-width: 160px;
            text-align: center;
            box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);
        }
        
        .stats-title {
            font-size: 0.9rem;
            color: #666;
            margin-bottom: 6px;
        }
        
        .stats-value {
            font-size: 1.4rem;
            font-weight: bold;
            color: #1a73e8;
        }
        
        .stats-box.male .stats-value {
            color: #4285f4;
        }
        
        .stats-box.female .stats-value {
            color: #f06292;
        }
        
        .stats-box.empty .stats-value {
            color: #666;
        }
        
        .stats-box.total .stats-value {
            color: #0f9d58;
        }
        
        .notification {
            position: fixed;
            top: 20px;
            right: 20px;
            padding: 15px 25px;
            background: #4CAF50;
            color: white;
            border-radius: 8px;
            box-shadow: 0 5px 15px rgba(0,0,0,0.2);
            z-index: 1000;
            transform: translateX(150%);
            transition: transform 0.3s ease;
        }
        
        .notification.show {
            transform: translateX(0);
        }
        
        .notification.error {
            background: #f44336;
        }
        
        /* 自定义布局弹窗 */
        .modal {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0, 0, 0, 0.5);
            display: flex;
            justify-content: center;
            align-items: center;
            z-index: 2000;
            opacity: 0;
            pointer-events: none;
            transition: opacity 0.3s ease;
        }
        
        .modal.active {
            opacity: 1;
            pointer-events: auto;
        }
        
        .modal-content {
            background-color: white;
            border-radius: 12px;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
            max-width: 400px;
            width: 90%;
            padding: 30px;
            transform: scale(0.9);
            transition: transform 0.3s ease;
        }
        
        .modal.active .modal-content {
            transform: scale(1);
        }
        
        .modal-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 20px;
        }
        
        .modal-title {
            font-size: 1.5rem;
            font-weight: bold;
            color: #1a73e8;
        }
        
        .close-modal {
            font-size: 1.5rem;
            cursor: pointer;
            color: #666;
            transition: color 0.3s ease;
        }
        
        .close-modal:hover {
            color: #333;
        }
        
        .form-group {
            margin-bottom: 20px;
        }
        
        .form-group label {
            display: block;
            font-size: 1.1rem;
            margin-bottom: 8px;
            color: #333;
        }
        
        .form-group input {
            width: 100%;
            padding: 12px;
            border: 1px solid #ddd;
            border-radius: 8px;
            font-size: 1rem;
            transition: border-color 0.3s ease;
        }
        
        .form-group input:focus {
            border-color: #1a73e8;
            outline: none;
        }
        
        .modal-footer {
            display: flex;
            justify-content: flex-end;
            gap: 15px;
        }
        
        .btn-cancel {
            background: linear-gradient(135deg, #f0f0f0, #e0e0e0);
            color: #333;
            box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
        }
        
        .btn-cancel:hover {
            background: linear-gradient(135deg, #e0e0e0, #d0d0d0);
            box-shadow: 0 4px 10px rgba(0, 0, 0, 0.15);
        }
        
        /* 身高排序弹窗 */
        .sort-options {
            display: flex;
            gap: 10px;
            margin-bottom: 20px;
        }
        
        .sort-option {
            flex: 1;
            text-align: center;
            padding: 10px;
            border: 2px solid #ddd;
            border-radius: 8px;
            cursor: pointer;
            transition: all 0.3s ease;
        }
        
        .sort-option.active {
            border-color: #1a73e8;
            background-color: rgba(26, 115, 232, 0.1);
        }
        
        @media (max-width: 900px) {
            .classroom {
                grid-template-columns: repeat(4, 1fr);
                gap: 12px;
            }
            
            .teacher-row {
                grid-template-columns: repeat(6, 1fr);
                gap: 10px;
                height: 100px;
            }
            
            .teacher-desk {
                grid-column: 2 / span 4;
            }
            
            .toolbar {
                flex-direction: column;
                align-items: center;
            }
            
            .btn-group {
                width: 100%;
                justify-content: center;
            }
            
            .status-bar {
                flex-wrap: wrap;
                gap: 12px;
                justify-content: center;
            }
            
            .stats-container {
                flex-wrap: wrap;
            }
            
            .student-name {
                font-size: 1.1rem;
            }
            
            .student-gender, .student-height {
                font-size: 0.8rem;
                padding: 2px 8px;
            }
        }
        
        @media (max-width: 600px) {
            .classroom {
                grid-template-columns: repeat(2, 1fr);
            }
            
            .teacher-row {
                grid-template-columns: repeat(2, 1fr);
                grid-template-rows: repeat(2, 1fr);
                height: 200px;
            }
            
            .side-seat:nth-child(1) { order: 1; }
            .side-seat:nth-child(2) { order: 2; }
            .side-seat:nth-child(5) { order: 3; }
            .side-seat:nth-child(6) { order: 4; }
            .teacher-desk {
                grid-column: 1 / span 2;
                grid-row: 1 / span 2;
                order: 5;
            }
            
            header h1 {
                font-size: 2rem;
            }
            
            .btn {
                padding: 12px 20px;
                font-size: 0.95rem;
            }
            
            .stats-container {
                flex-direction: column;
                align-items: center;
            }
            
            .stats-box {
                width: 100%;
            }
            
            .modal-content {
                max-width: 90%;
                padding: 20px;
            }
            
            .seat {
                height: 110px;
            }
            
            .student-name {
                font-size: 1rem;
            }
        }

        /* PDF打印专用样式 */
        @media print {
            body * {
                visibility: hidden;
            }
            .print-container, .print-container * {
                visibility: visible;
            }
            .print-container {
                position: absolute;
                left: 0;
                top: 0;
                width: 100%;
            }
        }
    </style>
</head>
<body>
    <div class="notification" id="notification">操作成功！</div>
    
    <div class="container">
        <header>
            <h1>学生座位表调整工具</h1>
            <div class="subtitle">讲台两侧座位 + 自定义布局 | 拖拽交换 | Excel导入 | 身高排序</div>
        </header>
        
        <div class="toolbar">
            <div class="file-upload">
                <button class="btn">
                    <i>📊</i> 导入Excel
                    <input type="file" id="excel-file" accept=".xlsx, .xls">
                </button>
            </div>
            
            <div class="btn-group">
                <button class="btn btn-random" id="random-btn">
                    <i>🔀</i> 随机排列
                </button>
                <button class="btn btn-height" id="height-btn">
                    <i>📏</i> 按身高排序
                </button>
                <button class="btn btn-reset" id="reset-btn">
                    <i>🔄</i> 重置座位
                </button>
                <button class="btn btn-pdf" id="pdf-btn">
                    <i>📄</i> 导出PDF
                </button>
                <button class="btn" id="layout-btn">
                    <i>🔲</i> 设置布局
                </button>
            </div>
        </div>
        
        <div class="classroom-container" id="print-target">
            <div class="classroom-header">教室座位布局（讲台两侧4个座位 + <span id="layout-info">8×8标准座位</span>）</div>
            <div class="classroom" id="classroom">
                <!-- 讲台行（第一行） -->
                <div class="teacher-row">
                    <div class="side-seat empty" data-id="1">
                        <div class="seat-position">1</div>
                        <div class="student-name">空</div>
                    </div>
                    <div class="side-seat empty" data-id="2">
                        <div class="seat-position">2</div>
                        <div class="student-name">空</div>
                    </div>
                    <div class="teacher-desk">讲台</div>
                    <div class="side-seat empty" data-id="3">
                        <div class="seat-position">3</div>
                        <div class="student-name">空</div>
                    </div>
                    <div class="side-seat empty" data-id="4">
                        <div class="seat-position">4</div>
                        <div class="student-name">空</div>
                    </div>
                </div>
                <!-- 普通座位行将通过JS动态生成 -->
            </div>
        </div>
        
        <div class="status-bar">
            <div class="stats-container">
                <div class="stats-box male">
                    <div class="stats-title">男生人数</div>
                    <div class="stats-value" id="male-count">0</div>
                </div>
                <div class="stats-box female">
                    <div class="stats-title">女生人数</div>
                    <div class="stats-value" id="female-count">0</div>
                </div>
                <div class="stats-box empty">
                    <div class="stats-title">空座位数</div>
                    <div class="stats-value" id="empty-count">68</div>
                </div>
                <div class="stats-box total">
                    <div class="stats-title">学生总数</div>
                    <div class="stats-value" id="student-count">0</div>
                </div>
                <div class="stats-box">
                    <div class="stats-title">总座位数</div>
                    <div class="stats-value" id="total-seats">68</div>
                </div>
            </div>
        </div>
        
        <div class="instructions">
            <h2>使用说明</h2>
            <ul>
                <li><strong>座位布局</strong>：讲台两侧各有2个座位（共4个），讲台下自定义布局（默认8×8，共64个座位），总计68个座位</li>
                <li><strong>Excel导入</strong>：点击"导入Excel"按钮，选择包含学生信息的Excel文件（第一列序号、第二列姓名、第三列性别、第四列身高，单位：厘米）</li>
                <li><strong>拖拽交换</strong>：拖动学生座位到另一个座位进行交换（可以与空位交换）</li>
                <li><strong>随机排列</strong>：点击"随机排列"按钮打乱当前学生座位顺序</li>
                <li><strong>按身高排序</strong>：点击"按身高排序"按钮，可选择从矮到高或从高到矮排列座位</li>
                <li><strong>本地存储</strong>：座位表状态会自动保存，刷新页面不会丢失数据</li>
                <li><strong>重置座位</strong>：点击"重置"按钮清空所有座位</li>
                <li><strong>导出PDF</strong>：点击"导出PDF"按钮生成当前座位表的PDF文件（包含学生姓名）</li>
                <li><strong>设置布局</strong>：点击"设置布局"按钮自定义普通座位区的行数和列数</li>
            </ul>
        </div>
    </div>
    
    <!-- 自定义布局弹窗 -->
    <div class="modal" id="layout-modal">
        <div class="modal-content">
            <div class="modal-header">
                <div class="modal-title">设置座位布局</div>
                <div class="close-modal" id="close-modal">&times;</div>
            </div>
            <div class="modal-body">
                <div class="form-group">
                    <label for="rows">行数：</label>
                    <input type="number" id="rows" min="1" max="20" value="8" placeholder="输入行数">
                </div>
                <div class="form-group">
                    <label for="columns">列数：</label>
                    <input type="number" id="columns" min="1" max="20" value="8" placeholder="输入列数">
                </div>
            </div>
            <div class="modal-footer">
                <button class="btn btn-cancel" id="cancel-layout">取消</button>
                <button class="btn" id="confirm-layout">确认</button>
            </div>
        </div>
    </div>
    
    <!-- 身高排序弹窗 -->
    <div class="modal" id="height-modal">
        <div class="modal-content">
            <div class="modal-header">
                <div class="modal-title">按身高排序</div>
                <div class="close-modal" id="close-height-modal">&times;</div>
            </div>
            <div class="modal-body">
                <div class="form-group">
                    <label>排序方式：</label>
                    <div class="sort-options">
                        <div class="sort-option active" data-order="asc">
                            从矮到高
                        </div>
                        <div class="sort-option" data-order="desc">
                            从高到矮
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <label>
                        <input type="checkbox" id="separate-gender" checked>
                        按性别分别排序
                    </label>
                </div>
            </div>
            <div class="modal-footer">
                <button class="btn btn-cancel" id="cancel-height">取消</button>
                <button class="btn btn-height" id="confirm-height">确认排序</button>
            </div>
        </div>
    </div>

    <script>
        // 座位数据（初始为8×8布局，共68个座位：讲台两侧4个 + 8×8=64个）
        let rows = 8;
        let columns = 8;
        let totalSeats = 4 + rows * columns; // 4个讲台两侧座位 + 普通座位
        let seats = Array(totalSeats).fill().map((_, index) => ({
            id: index + 1,
            name: "",
            gender: "",
            height: null,
            isEmpty: true,
            isSideSeat: index < 4 // 前4个是讲台两侧座位
        }));
        
        // 显示通知
        function showNotification(message, isError = false) {
            const notification = document.getElementById('notification');
            notification.textContent = message;
            notification.className = isError ? 'notification error' : 'notification';
            notification.classList.add('show');
            
            setTimeout(() => {
                notification.classList.remove('show');
            }, 3000);
        }
        
        // 从本地存储加载座位数据
        function loadSeatsFromStorage() {
            const savedSeats = localStorage.getItem('classroomSeats');
            const savedLayout = localStorage.getItem('classroomLayout');
            
            if (savedLayout) {
                try {
                    const { r, c } = JSON.parse(savedLayout);
                    if (typeof r === 'number' && typeof c === 'number') {
                        setLayout(r, c, false);
                    }
                } catch (e) {
                    console.error("解析布局数据失败:", e);
                }
            }
            
            if (savedSeats) {
                try {
                    const parsedSeats = JSON.parse(savedSeats);
                    if (Array.isArray(parsedSeats) && parsedSeats.length === totalSeats) {
                        seats = parsedSeats;
                        showNotification("已加载上次保存的座位表");
                        return true;
                    }
                } catch (e) {
                    console.error("解析本地存储数据失败:", e);
                }
            }
            return false;
        }
        
        // 保存座位数据到本地存储
        function saveSeatsToStorage() {
            localStorage.setItem('classroomSeats', JSON.stringify(seats));
            localStorage.setItem('classroomLayout', JSON.stringify({ r: rows, c: columns }));
        }
        
        // 设置布局
        function setLayout(newRows, newColumns, shouldSave = true) {
            // 保存当前学生数据
            const currentStudents = seats.filter(seat => !seat.isEmpty);
            
            // 更新布局参数
            rows = newRows;
            columns = newColumns;
            totalSeats = 4 + rows * columns;
            
            // 更新界面显示
            document.getElementById('layout-info').textContent = `${rows}×${columns}座位`;
            document.getElementById('total-seats').textContent = totalSeats;
            
            // 创建新的座位数组
            seats = Array(totalSeats).fill().map((_, index) => ({
                id: index + 1,
                name: "",
                gender: "",
                height: null,
                isEmpty: true,
                isSideSeat: index < 4
            }));
            
            // 恢复学生数据（如果有空间）
            const maxStudents = Math.min(currentStudents.length, totalSeats);
            for (let i = 0; i < maxStudents; i++) {
                seats[i] = { ...currentStudents[i], id: i + 1 };
            }
            
            if (shouldSave) {
                saveSeatsToStorage();
                showNotification(`座位布局已更新为 ${rows}×${columns}`);
            }
        }
        
        // 初始化座位
        function initSeats() {
            // 尝试从本地存储加载
            const loaded = loadSeatsFromStorage();
            
            const classroom = document.getElementById('classroom');
            
            // 清空普通座位区（保留讲台行）
            const teacherRow = classroom.querySelector('.teacher-row');
            classroom.innerHTML = '';
            classroom.appendChild(teacherRow);
            
            // 设置网格模板列
            classroom.style.gridTemplateColumns = `repeat(${columns}, 1fr)`;
            
            // 生成普通座位区
            for (let row = 0; row < rows; row++) {
                for (let col = 0; col < columns; col++) {
                    const seatIndex = row * columns + col + 4; // 前4个是讲台两侧座位
                    const seat = seats[seatIndex];
                    
                    const seatElement = document.createElement('div');
                    seatElement.className = 'seat ' + (seat.isEmpty ? 'empty' : seat.gender === '男' ? 'male' : 'female');
                    seatElement.dataset.id = seat.id;
                    seatElement.draggable = true;
                    
                    // 更新座位内容结构：位置信息在上，姓名在中间，性别和身高并排显示在下方
                    seatElement.innerHTML = `
                        <div class="seat-position">${seat.id}</div>
                        <div class="student-name">${seat.isEmpty ? '空' : seat.name}</div>
                        ${!seat.isEmpty ? `
                            <div class="student-details">
                                <div class="student-gender">${seat.gender}</div>
                                ${seat.height ? `<div class="student-height">${seat.height}cm</div>` : ''}
                            </div>
                        ` : ''}
                    `;
                    
                    // 添加拖拽事件
                    seatElement.addEventListener('dragstart', handleDragStart);
                    seatElement.addEventListener('dragover', handleDragOver);
                    seatElement.addEventListener('dragenter', handleDragEnter);
                    seatElement.addEventListener('dragleave', handleDragLeave);
                    seatElement.addEventListener('drop', handleDrop);
                    seatElement.addEventListener('dragend', handleDragEnd);
                    
                    classroom.appendChild(seatElement);
                }
            }
            
            // 添加讲台两侧座位的拖拽事件
            const sideSeats = document.querySelectorAll('.side-seat');
            sideSeats.forEach(seat => {
                const seatId = parseInt(seat.dataset.id);
                const seatData = seats.find(s => s.id === seatId);
                
                seat.className = 'side-seat ' + (seatData.isEmpty ? 'empty' : seatData.gender === '男' ? 'male' : 'female');
                seat.innerHTML = `
                    <div class="seat-position">${seatId}</div>
                    <div class="student-name">${seatData.isEmpty ? '空' : seatData.name}</div>
                    ${!seatData.isEmpty ? `
                        <div class="student-details">
                            <div class="student-gender">${seatData.gender}</div>
                            ${seatData.height ? `<div class="student-height">${seatData.height}cm</div>` : ''}
                        </div>
                    ` : ''}
                `;
                
                seat.draggable = true;
                seat.addEventListener('dragstart', handleDragStart);
                seat.addEventListener('dragover', handleDragOver);
                seat.addEventListener('dragenter', handleDragEnter);
                seat.addEventListener('dragleave', handleDragLeave);
                seat.addEventListener('drop', handleDrop);
                seat.addEventListener('dragend', handleDragEnd);
            });
            
            // 更新统计数据
            updateStudentStats();
        }
        
        // 拖拽功能
        let draggedSeat = null;
        
        function handleDragStart(e) {
            const seatId = parseInt(this.dataset.id);
            const seat = seats.find(s => s.id === seatId);
            
            // 空位不能拖动
            if (seat.isEmpty) {
                e.preventDefault();
                return;
            }
            
            draggedSeat = seat;
            this.classList.add('dragging');
            e.dataTransfer.effectAllowed = 'move';
            e.dataTransfer.setData('text/plain', seatId.toString());
        }
        
        function handleDragOver(e) {
            if (e.preventDefault) {
                e.preventDefault();
            }
            
            e.dataTransfer.dropEffect = 'move';
            return false;
        }
        
        function handleDragEnter(e) {
            this.classList.add('drag-over');
        }
        
        function handleDragLeave() {
            this.classList.remove('drag-over');
        }
        
        function handleDrop(e) {
            if (e.stopPropagation) {
                e.stopPropagation();
            }
            
            const seatId = parseInt(this.dataset.id);
            const targetSeat = seats.find(s => s.id === seatId);
            
            if (draggedSeat && draggedSeat.id !== targetSeat.id) {
                if (targetSeat.isEmpty) {
                    // 目标为空，移动学生到该座位
                    targetSeat.name = draggedSeat.name;
                    targetSeat.gender = draggedSeat.gender;
                    targetSeat.height = draggedSeat.height;
                    targetSeat.isEmpty = false;
                    
                    // 清空原座位
                    draggedSeat.name = "";
                    draggedSeat.gender = "";
                    draggedSeat.height = null;
                    draggedSeat.isEmpty = true;
                } else {
                    // 非空，交换
                    swapSeats(draggedSeat, targetSeat);
                }
                
                renderSeats();
                saveSeatsToStorage(); // 保存到本地存储
                showNotification("座位调整成功！");
            }
            
            this.classList.remove('drag-over');
            return false;
        }
        
        function handleDragEnd() {
            this.classList.remove('dragging', 'drag-over');
            draggedSeat = null;
        }
        
        // 交换座位
        function swapSeats(seat1, seat2) {
            const nameTemp = seat1.name;
            const genderTemp = seat1.gender;
            const heightTemp = seat1.height;
            const isEmptyTemp = seat1.isEmpty;
            
            seat1.name = seat2.name;
            seat1.gender = seat2.gender;
            seat1.height = seat2.height;
            seat1.isEmpty = seat2.isEmpty;
            
            seat2.name = nameTemp;
            seat2.gender = genderTemp;
            seat2.height = heightTemp;
            seat2.isEmpty = isEmptyTemp;
        }
        
        // 渲染所有座位
        function renderSeats() {
            // 更新讲台两侧座位
            const sideSeats = document.querySelectorAll('.side-seat');
            sideSeats.forEach(seatElement => {
                const seatId = parseInt(seatElement.dataset.id);
                const seat = seats.find(s => s.id === seatId);
                
                // 重置类名
                seatElement.className = 'side-seat';
                seatElement.classList.add(seat.isEmpty ? 'empty' : seat.gender === '男' ? 'male' : 'female');
                
                // 更新内容
                seatElement.innerHTML = `
                    <div class="seat-position">${seatId}</div>
                    <div class="student-name">${seat.isEmpty ? '空' : seat.name}</div>
                    ${!seat.isEmpty ? `
                        <div class="student-details">
                            <div class="student-gender">${seat.gender}</div>
                            ${seat.height ? `<div class="student-height">${seat.height}cm</div>` : ''}
                        </div>
                    ` : ''}
                `;
            });
            
            // 更新普通座位
            const seatElements = document.querySelectorAll('.seat:not(.side-seat)');
            seatElements.forEach(seatElement => {
                const seatId = parseInt(seatElement.dataset.id);
                const seat = seats.find(s => s.id === seatId);
                
                // 重置类名
                seatElement.className = 'seat';
                seatElement.classList.add(seat.isEmpty ? 'empty' : seat.gender === '男' ? 'male' : 'female');
                
                // 更新内容
                seatElement.innerHTML = `
                    <div class="seat-position">${seat.id}</div>
                    <div class="student-name">${seat.isEmpty ? '空' : seat.name}</div>
                    ${!seat.isEmpty ? `
                        <div class="student-details">
                            <div class="student-gender">${seat.gender}</div>
                            ${seat.height ? `<div class="student-height">${seat.height}cm</div>` : ''}
                        </div>
                    ` : ''}
                `;
            });
            
            // 更新统计数据
            updateStudentStats();
        }
        
        // 更新学生统计信息
        function updateStudentStats() {
            const totalSeats = seats.length;
            const occupiedSeats = seats.filter(seat => !seat.isEmpty).length;
            const maleCount = seats.filter(seat => !seat.isEmpty && seat.gender === '男').length;
            const femaleCount = seats.filter(seat => !seat.isEmpty && seat.gender === '女').length;
            const emptyCount = totalSeats - occupiedSeats;
            
            document.getElementById('male-count').textContent = maleCount;
            document.getElementById('female-count').textContent = femaleCount;
            document.getElementById('empty-count').textContent = emptyCount;
            document.getElementById('student-count').textContent = occupiedSeats;
            document.getElementById('total-seats').textContent = totalSeats;
        }
        
        // 导入Excel - 支持身高数据
        document.getElementById('excel-file').addEventListener('change', function(e) {
            const file = e.target.files[0];
            if (!file) return;
            
            const reader = new FileReader();
            reader.onload = function(e) {
                try {
                    const data = new Uint8Array(e.target.result);
                    const workbook = XLSX.read(data, {type: 'array'});
                    
                    // 获取第一个工作表
                    const worksheet = workbook.Sheets[workbook.SheetNames[0]];
                    const jsonData = XLSX.utils.sheet_to_json(worksheet, {header: 1});
                    
                    // 处理数据 (跳过标题行)
                    const students = jsonData.slice(1).filter(row => row && row.length >= 3).map(row => ({
                        name: row[1],
                        gender: row[2],
                        height: row[3] ? parseFloat(row[3]) : null
                    }));
                    
                    if (students.length === 0) {
                        showNotification("Excel中没有找到学生数据，请检查格式", true);
                        return;
                    }
                    
                    // 重置座位数据
                    seats.forEach((seat, index) => {
                        if (index < students.length) {
                            const student = students[index];
                            seat.name = student.name || "";
                            seat.gender = student.gender || "";
                            seat.height = student.height;
                            seat.isEmpty = false;
                        } else {
                            seat.name = "";
                            seat.gender = "";
                            seat.height = null;
                            seat.isEmpty = true;
                        }
                    });
                    
                    renderSeats();
                    saveSeatsToStorage();
                    showNotification(`成功导入 ${students.length} 名学生数据`);
                } catch (error) {
                    console.error("Excel导入错误:", error);
                    showNotification("Excel导入失败，请检查文件格式", true);
                }
            };
            reader.readAsArrayBuffer(file);
        });
        
        // 随机排列
        document.getElementById('random-btn').addEventListener('click', function() {
            // 获取所有非空座位
            const nonEmptySeats = seats.filter(seat => !seat.isEmpty);
            
            if (nonEmptySeats.length === 0) {
                showNotification("没有学生数据，无法随机排列", true);
                return;
            }
            
            // 随机打乱顺序
            for (let i = nonEmptySeats.length - 1; i > 0; i--) {
                const j = Math.floor(Math.random() * (i + 1));
                [nonEmptySeats[i].name, nonEmptySeats[j].name] = [nonEmptySeats[j].name, nonEmptySeats[i].name];
                [nonEmptySeats[i].gender, nonEmptySeats[j].gender] = [nonEmptySeats[j].gender, nonEmptySeats[i].gender];
                [nonEmptySeats[i].height, nonEmptySeats[j].height] = [nonEmptySeats[j].height, nonEmptySeats[i].height];
            }
            
            // 将打乱后的学生放回座位
            let index = 0;
            seats.forEach(seat => {
                if (!seat.isEmpty) {
                    const student = nonEmptySeats[index++];
                    seat.name = student.name;
                    seat.gender = student.gender;
                    seat.height = student.height;
                }
            });
            
            renderSeats();
            saveSeatsToStorage();
            showNotification("座位随机排列完成");
        });
        
        // 按身高排序功能
        let sortOrder = "asc"; // 默认从矮到高
        let separateGender = true; // 默认按性别分别排序
        
        // 打开身高排序弹窗
        document.getElementById('height-btn').addEventListener('click', function() {
            const nonEmptySeats = seats.filter(seat => !seat.isEmpty);
            
            if (nonEmptySeats.length === 0) {
                showNotification("没有学生数据，无法按身高排序", true);
                return;
            }
            
            // 检查是否有身高数据
            const hasHeightData = nonEmptySeats.some(seat => seat.height);
            if (!hasHeightData) {
                showNotification("学生数据中没有身高信息，请导入包含身高的Excel", true);
                return;
            }
            
            // 重置排序选项
            document.querySelectorAll('.sort-option').forEach(option => {
                option.classList.remove('active');
            });
            document.querySelector(`.sort-option[data-order="${sortOrder}"]`).classList.add('active');
            document.getElementById('separate-gender').checked = separateGender;
            
            // 显示弹窗
            document.getElementById('height-modal').classList.add('active');
        });
        
        // 关闭身高排序弹窗
        document.getElementById('close-height-modal').addEventListener('click', function() {
            document.getElementById('height-modal').classList.remove('active');
        });
        
        document.getElementById('cancel-height').addEventListener('click', function() {
            document.getElementById('height-modal').classList.remove('active');
        });
        
        // 选择排序方式
        document.querySelectorAll('.sort-option').forEach(option => {
            option.addEventListener('click', function() {
                document.querySelectorAll('.sort-option').forEach(opt => opt.classList.remove('active'));
                this.classList.add('active');
                sortOrder = this.dataset.order;
            });
        });
        
        // 切换是否按性别分别排序
        document.getElementById('separate-gender').addEventListener('change', function() {
            separateGender = this.checked;
        });
        
        // 确认按身高排序
        document.getElementById('confirm-height').addEventListener('click', function() {
            // 获取所有非空座位
            let nonEmptySeats = seats.filter(seat => !seat.isEmpty);
            
            // 按身高排序
            if (separateGender) {
                // 按性别分组排序
                const maleStudents = nonEmptySeats.filter(seat => seat.gender === '男');
                const femaleStudents = nonEmptySeats.filter(seat => seat.gender === '女');
                const otherStudents = nonEmptySeats.filter(seat => !['男', '女'].includes(seat.gender));
                
                // 分别排序
                sortStudentsByHeight(maleStudents, sortOrder);
                sortStudentsByHeight(femaleStudents, sortOrder);
                sortStudentsByHeight(otherStudents, sortOrder);
                
                // 合并排序后的结果
                nonEmptySeats = [...maleStudents, ...femaleStudents, ...otherStudents];
            } else {
                // 不分组，统一排序
                sortStudentsByHeight(nonEmptySeats, sortOrder);
            }
            
            // 将排序后的学生放回座位
            let index = 0;
            seats.forEach(seat => {
                if (!seat.isEmpty) {
                    const student = nonEmptySeats[index++];
                    seat.name = student.name;
                    seat.gender = student.gender;
                    seat.height = student.height;
                }
            });
            
            renderSeats();
            saveSeatsToStorage();
            document.getElementById('height-modal').classList.remove('active');
            showNotification(`座位已按身高${sortOrder === 'asc' ? '从矮到高' : '从高到矮'}排序`);
        });
        
        // 按身高排序学生
        function sortStudentsByHeight(students, order) {
            students.sort((a, b) => {
                // 没有身高数据的放最后
                if (a.height === null && b.height === null) return 0;
                if (a.height === null) return 1;
                if (b.height === null) return -1;
                
                // 按身高排序
                return order === 'asc' ? a.height - b.height : b.height - a.height;
            });
        }
        
        // 重置座位
        document.getElementById('reset-btn').addEventListener('click', function() {
            if (confirm("确定要重置所有座位吗？这将清除所有学生数据。")) {
                seats.forEach(seat => {
                    seat.name = "";
                    seat.gender = "";
                    seat.height = null;
                    seat.isEmpty = true;
                });
                renderSeats();
                saveSeatsToStorage();
                showNotification("座位表已重置");
            }
        });
        
        // 导出PDF
        document.getElementById('pdf-btn').addEventListener('click', function() {
            const targetElement = document.getElementById('print-target');
            
            if (!targetElement) {
                showNotification("找不到座位表内容", true);
                return;
            }
            
            showNotification("正在生成PDF，请稍候...");
            
            // 创建一个临时元素用于生成PDF
            const tempContainer = document.createElement('div');
            tempContainer.style.width = '100%';
            tempContainer.style.background = '#fff';
            tempContainer.style.padding = '20px';
            tempContainer.style.boxSizing = 'border-box';
            
            // 克隆目标内容
            const clonedContent = targetElement.cloneNode(true);
            
            // 调整克隆内容的样式，确保文字清晰
            const classroom = clonedContent.querySelector('.classroom');
            if (classroom) {
                classroom.style.gap = '8px';
                classroom.style.padding = '15px';
            }
            
            // 调整座位和文字大小以确保姓名显示清晰
            const allSeats = clonedContent.querySelectorAll('.seat, .side-seat');
            allSeats.forEach(seat => {
                seat.style.height = '70px';
                seat.style.padding = '8px';
                
                // 调整姓名样式
                const nameElement = seat.querySelector('.student-name');
                if (nameElement) {
                    nameElement.style.fontSize = '12px';
                    nameElement.style.fontWeight = 'bold';
                    nameElement.style.color = '#000';
                }
                
                // 调整性别和身高样式
                const detailsElements = seat.querySelectorAll('.student-gender, .student-height');
                detailsElements.forEach(el => {
                    el.style.fontSize = '10px';
                    el.style.color = '#000';
                });
            });
            
            // 添加标题
            const title = document.createElement('h2');
            title.style.textAlign = 'center';
            title.style.margin = '0 0 20px 0';
            title.style.fontSize = '18px';
            title.textContent = '学生座位表';
            
            // 添加统计信息
            const statsContainer = document.createElement('div');
            statsContainer.style.display = 'flex';
            statsContainer.style.justifyContent = 'space-around';
            statsContainer.style.margin = '0 0 20px 0';
            statsContainer.style.fontSize = '12px';
            statsContainer.innerHTML = document.querySelector('.status-bar').innerHTML;
            
            // 组装临时容器
            tempContainer.appendChild(title);
            tempContainer.appendChild(statsContainer);
            tempContainer.appendChild(clonedContent);
            
            // 将临时容器添加到页面但隐藏
            tempContainer.style.position = 'absolute';
            tempContainer.style.top = '-10000px';
            tempContainer.style.left = '-10000px';
            document.body.appendChild(tempContainer);
            
            // 计算最佳PDF尺寸
            const useLandscape = columns > 8; // 列数多则用横向
            const pdf = new jspdf.jsPDF({
                orientation: useLandscape ? 'landscape' : 'portrait',
                unit: 'mm',
                format: 'a4'
            });
            
            // 生成PDF - 使用优化的配置确保文字渲染
            html2canvas(tempContainer, {
                scale: 3, // 提高缩放比例以获得更高清晰度
                useCORS: true,
                logging: false,
                scrollY: -window.scrollY,
                windowWidth: tempContainer.offsetWidth,
                letterRendering: true, // 优化文字渲染
                allowTaint: true,
                backgroundColor: null // 使用透明背景
            }).then(canvas => {
                // 计算图像尺寸和位置
                const imgWidth = useLandscape ? 270 : 190;
                const imgHeight = canvas.height * imgWidth / canvas.width;
                const marginX = useLandscape ? 10 : 10;
                const marginY = 10;
                
                // 检查是否需要多页
                const pageHeight = useLandscape ? 180 : 270;
                let position = marginY;
                
                // 如果内容高度超过一页，分割成多页
                if (imgHeight > pageHeight - marginY * 2) {
                    let heightLeft = imgHeight;
                    let startY = 0;
                    
                    while (heightLeft > 0) {
                        const pageHeightCurrent = heightLeft > pageHeight ? pageHeight : heightLeft;
                        
                        const canvasData = canvas.getContext('2d').getImageData(
                            0, 
                            startY, 
                            canvas.width, 
                            canvas.height * pageHeightCurrent / imgHeight
                        );
                        
                        const newCanvas = document.createElement('canvas');
                        newCanvas.width = canvas.width;
                        newCanvas.height = canvas.height * pageHeightCurrent / imgHeight;
                        newCanvas.getContext('2d').putImageData(canvasData, 0, 0);
                        
                        const imgData = newCanvas.toDataURL('image/png');
                        
                        pdf.addImage(imgData, 'PNG', marginX, position, imgWidth, pageHeightCurrent);
                        
                        heightLeft -= pageHeightCurrent;
                        startY += canvas.height * pageHeightCurrent / imgHeight;
                        position = marginY;
                        
                        if (heightLeft > 0) {
                            pdf.addPage();
                        }
                    }
                } else {
                    // 单页
                    const imgData = canvas.toDataURL('image/png');
                    pdf.addImage(imgData, 'PNG', marginX, marginY, imgWidth, imgHeight);
                }
                
                pdf.save('学生座位表.pdf');
                
                // 移除临时容器
                document.body.removeChild(tempContainer);
                
                showNotification("PDF导出成功！");
            }).catch(error => {
                console.error("PDF导出错误:", error);
                showNotification("PDF导出失败，请重试", true);
                
                // 移除临时容器
                document.body.removeChild(tempContainer);
            });
        });
        
        // 自定义布局功能
        const layoutModal = document.getElementById('layout-modal');
        const rowsInput = document.getElementById('rows');
        const columnsInput = document.getElementById('columns');
        
        // 打开布局设置弹窗
        document.getElementById('layout-btn').addEventListener('click', function() {
            rowsInput.value = rows;
            columnsInput.value = columns;
            layoutModal.classList.add('active');
        });
        
        // 关闭弹窗
        document.getElementById('close-modal').addEventListener('click', function() {
            layoutModal.classList.remove('active');
        });
        
        document.getElementById('cancel-layout').addEventListener('click', function() {
            layoutModal.classList.remove('active');
        });
        
        // 确认布局设置
        document.getElementById('confirm-layout').addEventListener('click', function() {
            const newRows = parseInt(rowsInput.value);
            const newColumns = parseInt(columnsInput.value);
            
            if (isNaN(newRows) || isNaN(newColumns) || newRows < 1 || newColumns < 1 || newRows > 20 || newColumns > 20) {
                showNotification("请输入有效的行数和列数（1-20之间）", true);
                return;
            }
            
            setLayout(newRows, newColumns);
            initSeats();
            layoutModal.classList.remove('active');
        });
        
        // 点击模态框外部关闭
        layoutModal.addEventListener('click', function(e) {
            if (e.target === layoutModal) {
                layoutModal.classList.remove('active');
            }
        });
        
        // 点击身高排序模态框外部关闭
        document.getElementById('height-modal').addEventListener('click', function(e) {
            if (e.target === document.getElementById('height-modal')) {
                document.getElementById('height-modal').classList.remove('active');
            }
        });
        
        // 初始化
        window.onload = initSeats;
    </script>
</body>
</html>
    